package com.jie.server.core.ssl.util;

import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.jie.common.util.BytesUtil;
import com.jie.server.core.ssl.entity.ServerSslMessage;
import com.jie.server.core.ssl.properties.CaProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;

/**
 * @author XieZhiJie
 * @date 2022/04/22 11:42
 */
public class ServerSslUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServerSslUtil.class);

    /**
     * 生成服务器的公钥私钥与"证书"
     * CA的公钥密钥也由服务器来生成, 生成后需要将公钥交给客户端, 服务器保存私钥, 用于生成证书
     * @param flag 是否生成
     */
    public static ServerSslMessage initServerSslMessage(boolean flag) {
        if (flag) {
            return initServerSslMessage();
        }
        return null;
    }

    /**
     * 生成服务器的公钥私钥与"证书"
     * 每次启动服务器都重新生成服务器公钥和私钥
     * CA公钥私钥由服务器模拟生成, 不会再变
     */
    private static ServerSslMessage initServerSslMessage() {
        LOGGER.info("ssl信息初始化开始...");

        // 1.生成服务器的公钥密钥
        KeyPair keyPair = KeyUtil.generateKeyPair("RSA");

        // 2.生成服务器的证书: 用CA私钥Encode(公钥长度[4字节] + 服务器公钥 + SHA1(服务器公钥))
        String publicKeyDigest = SecureUtil.sha1(new String(keyPair.getPublic().getEncoded()));
        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        byte[] digestBytes = publicKeyDigest.getBytes(StandardCharsets.UTF_8);
        byte[] certificateByte = BytesUtil.packageTwoBytesWithLengthBytes(publicKeyBytes, digestBytes);

        // 用私钥加密证书
        RSA rsa = new RSA(CaProperties.PRIVATE_KEY_BYTES, CaProperties.PUBLIC_KEY_BYTES);
        certificateByte = rsa.encrypt(certificateByte, KeyType.PrivateKey);

        LOGGER.info("ssl信息初始化成功...");
        return new ServerSslMessage(certificateByte, publicKeyBytes, keyPair.getPrivate().getEncoded());
    }

}
